using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Hosting;
using EPiServer.Security;
using System.ServiceModel.Syndication;
using NCMIS.Client;
using NCMIS.ServiceModel.Syndication;
using NCMIS.ObjectModel.Rest;

namespace EPiServer.Web.Hosting
{
    public class CmisFile : UnifiedFile
    {
        private string _permanentLinkVirtualPath = String.Empty;
        private DateTime _changed = DateTime.UtcNow;
        private DateTime _created = DateTime.UtcNow;

        private CmisSummary _summary;
        private CmisWebRequest _cmisWebReq;
        private long _contentLength =0;

        public bool ShouldCreateFile = false;

        public CmisWebRequest WebRequest
        {
            get
            {
                return _cmisWebReq;
            }
        }

        // Properties
        public Uri SelfURI
        {
            get;
            set;
        }

        public Uri ParentsChildrenURI
        {
            get;
            set;
        }

        public Uri UpURI
        {
            get;
            set;
        }

        public Uri ContentURI
        {
            get;
            set;
        }
 
        /// <summary>
        /// CmisFile class constructor.
        /// </summary>
        /// <param name="provider">The provider which was responsible for delivering this
        /// file from it underlying file system.</param>
        /// <param name="virtualPath">The file's VirtualPath.</param>
        public CmisFile(UnifiedDirectory parent, VirtualPathUnifiedProvider provider, string virtualPath, bool byPassAccessCheck, long contentLength) : base(parent, provider, virtualPath, byPassAccessCheck)
        {
            _summary = new CmisSummary();
            _created = DateTime.UtcNow;

            _contentLength = contentLength;

            // Create a (CMIS) web request
            _cmisWebReq = provider.GetCmisWebRequest();
        }

        /// <summary>
        /// File changed property
        /// </summary>
        public override DateTime Changed
        {
            get 
            { 
                return _changed; 
            }
        }

        /// <summary>
        /// File created property
        /// </summary>
        public override DateTime Created
        {
            get 
            { 
                return _created; 
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override string PermanentLinkVirtualPath 
        {
            get 
            { 
                return _permanentLinkVirtualPath;
            } 
        }

        /// <summary>
        /// Gets the parent directory. By using the hosting environment we ensure that
        /// the path requested isn't above top level root dir, and attempting to cast
        /// to provider implemetation class avoids mixing of filesystems.
        /// </summary>
        public override UnifiedDirectory Parent
        {
            get
            {
                return HostingEnvironment.VirtualPathProvider.GetDirectory(VirtualPathUtility.GetDirectory(VirtualPath)) as CmisDirectory;
            }
        }

        /// <summary>
        /// The file content length.
        /// </summary>
        public override long Length
        {
            get 
            {
                return _contentLength; 
            }
        }

        internal void SetLength(long length)
        {
            _contentLength = length;
        }

        /// <summary>
        /// Lets the Parent directory remove the reference to this file.
        /// </summary>
        public override void Delete()
        {
            CmisDirectory parent = Parent as CmisDirectory;
            if (parent != null)
            {
                ((CmisDirectory)parent).DeleteFileRefByName(Name);
            }

            if (SelfURI != null)
            {
                parent.DeleteFile(SelfURI);
            }
        }

        /// <summary>
        /// Copies this file to a new CmisDirectory.
        /// </summary>
        /// <param name="virtualDir"></param>
        public override void CopyTo(string virtualDir)
        {
            CmisDirectory destinationDir = HostingEnvironment.VirtualPathProvider.GetDirectory(
                VirtualPathUtility.GetDirectory(VirtualPath)) as CmisDirectory;

            if (destinationDir == null)
            {
                throw new ArgumentException("Parameter virtualPath passed to CopyTo is invalid. Either " +
                    "not existing or returning a implementation incompatible with the CmisDirectory class.");
            }

            UnifiedFile destinationFile = destinationDir.CreateFile(Name);
            UnifiedFile.CopyFile(this, destinationFile);
        }

        /// <summary>
        /// Overload of CopyTo(virtualPath) in case the VirtualFile must be identified
        /// in backend system the fileId param can be used. 
        /// </summary>
        /// <param name="virtualDir"></param>
        /// <param name="fileId"></param>
        public override void CopyTo(string virtualDir, Guid fileId)
        {
            CopyTo(virtualDir, Guid.Empty);
        }


        /// <summary>
        /// Moves this file to another virtual directory.
        /// </summary>
        /// <param name="virtualDir"></param>
        public override void MoveTo(string virtualDir)
        {
            CmisDirectory destinationDir = HostingEnvironment.VirtualPathProvider.GetDirectory(
                    VirtualPathUtility.GetDirectory(VirtualPath)) as CmisDirectory;
            string newFileName = VirtualPathUtility.GetFileName(virtualDir);

            if (destinationDir == null)
            {
                throw new ArgumentException("Parameter virtualPath passed to CopyTo is invalid. Either " +
                    "not existing or returning a implementation incompatible with the CmisDirectory class.");
            }

            UnifiedFile destinationFile = destinationDir.CreateFile(newFileName);
            UnifiedFile.CopyFile(this, destinationFile);
            Delete();
        }

        /// <summary>
        /// Open a file with with respect to access rights.
        /// </summary>
        /// <param name="mode"></param>
        /// <param name="access"></param>
        /// <param name="share"></param>
        /// <returns></returns>
        public override Stream Open(FileMode mode, FileAccess access, FileShare share)
        {
            /*
            if (access == FileAccess.Read)
            {
                return new CmisStream(this, false);
            }
            else
            {
                return new CmisStream(this, true);
            }
            */
            return new CmisFileStream(this, access);
        } 
         

        /// <summary>
        /// From VirtualPath class, same as open just for reading.
        /// </summary>
        /// <returns></returns>
        public override Stream Open()
        {
            return Open(FileMode.Open, FileAccess.Read, FileShare.Read);
        }

        /// <summary>
        /// Gets the file summary.
        /// </summary>
        public override IUnifiedSummary Summary
        {
            get 
            { 
                return _summary; 
            }
        }
    }
}
